home *** CD-ROM | disk | FTP | other *** search
- /*
-
- binder.hpp
- 10-25-91
- Loose Data Binder v 1.5
-
- Copyright 1991
- John W. Small
- All rights reserved
-
- PSW / Power SoftWare
- P.O. Box 10072
- McLean, Virginia 22102 8072 USA
-
- John Small
- Voice: (703) 759-3838
- CIS: 73757,2233
-
- */
-
-
- #ifndef BINDER_HPP
- #define BINDER_HPP
-
- #include <limits.h> // UINT_MAX
-
- /*
-
- The "Loose Data Binder", or Binder for short, binds
- any type of data together in a hybrid stack-queue-
- deque-list-array structure. Like a loose leaf
- notebook where you can insert or arrange leafs in
- any fashion, the "Loose Data Binder" allows you to
- collect and arrange data in any fashion. Think of
- the Binder as an elastic array of void pointers.
- The Binder is the equivalent of an extensive
- container class hierarchy but without the confusing
- complexity of a towering hierarchy.
-
- */
-
-
- /* Various pointers and their NULLs */
-
- typedef void * voiD;
- #define voiD0 ((voiD)0)
- typedef voiD * voiDV;
- #define voiDV0 ((voiDV)0)
-
-
- enum BDR_DEFAULTS {
-
- BDR_MAXNODES = (UINT_MAX/sizeof(voiD)),
- BDR_LIMIT = 20,
- BDR_DELTA = 10,
- BDR_NOTFOUND = BDR_MAXNODES
- };
-
- enum BDR_FLAG_BITS {
-
- BDR_SORTED = 0x01,
- BDR_OK_FREE = 0x02,
- BDR_NO_FREE = 0x00
- };
-
-
- /* Search/sort compare function pointer type: */
-
- typedef int (*BDRcomparE)(const voiD D1, const voiD D2);
- #define BDRcomparE0 ((BDRcomparE)0)
-
-
- /* Function pointer types for the Binder iterators: */
-
- typedef void (*BDRforEachBlocK)
- (voiD D, voiD M, voiD A);
- typedef int (*BDRdetectBlocK)
- (voiD D, voiD M);
- class Binder;
- typedef Binder * BindeR;
- typedef void (*BDRcollectBlocK)
- (voiD D, BindeR R, voiD M, voiD A);
-
- /*
- Gimmick for constructing without initializing:
- to be used for loading instances from a stream
- (see sbinder.hpp).
- */
-
- typedef BindeR * UniqueBinderConST;
- #define OnlyInitBinderVFT ((UniqueBinderConST)0)
-
-
- /*
- Gaurrantees Dfree() is only invoked when
- (flags & BDR_OK_FREE) != 0.
- */
-
- #define DFREE(Dexp) ((flags & BDR_OK_FREE)? Dfree(Dexp): 0)
-
-
- class SBinder; // forward declaration
-
-
- /*
- Binder nodes must be all either statically or
- dynamically allocated as indicated by the
- BDR_OK_FREE flag. The Binder defaults to
- BDR_NO_FREE or static meaning its deleting
- primitives are inhibited and upon Binder destruction
- any remaining nodes are simply left unbound and
- undeleted. If you wish to dispose of the nodes then
- be SURE that every node is dynamically allocated and
- that you set the BDR_OK_FREE flag in the constructor
- call. See Dfree() for details on calling node
- destructors.
- */
-
- class Binder {
- friend SBinder; // SBinder::load, SBinder::store
- unsigned lowLimit, lowThreshold, first;
- voiDV linkS;
- unsigned limit, delta, nodes, maxNodes;
- unsigned curNode, flags;
- BDRcomparE comparE;
- protected:
- void construct(unsigned flags, unsigned maxNodes,
- unsigned limit, unsigned delta);
- virtual int Dfree(voiD D)
- /*
- Dfree() is called by any Binder
- primitive that attempts to delete
- the data, D, it is unbinding, e.g.
- atFree(), popFree(), etc. The
- Binder must be constructed with
- BDR_OK_FREE for Dfree() to be
- called. In other words it is
- guaranteed that Dfree() is never
- called when BDR_OK_FREE is absent.
- If D is NULL then zero must be
- returned otherwise a nonzero value
- must be returned regardless of
- whether or not an overriding
- function is successful in deleting
- its data. Override this function to
- implement calling your own node
- destructors.
- */
- { return (D? delete D, 1 : 0); }
- virtual int Dattach(voiD)
- /*
- Dattach() is called by any Binder
- primitive that attempts to bind
- data, e.g. atIns(), push(), etc.
- This allows the data to become aware
- of the binding process by overriding
- Dattach(). The voiD parameter is a
- pointer to the data about to be
- bound and guaranteed never to be
- NULL! If and only if the data can't
- attach itself to the Binder, as
- defined by the overriding function,
- should zero be returned. Any
- overriding function should only
- "link" itself to the Binder but
- should not use the implicit "this"
- pointer to access Binder within the
- overriding function. This
- restriction applies because Binder
- data may be in a transition state
- when Dattach() is called. It is
- however permissible to store the
- "this" pointer within the data being
- bound for later use in accessing
- Binder data.
- */
- { return 1; }
- virtual void Ddetach(voiD)
- /*
- Ddetach() is called by any Binder
- primitive that attempts to unbind
- data, e.g. atDel(), pop(), etc.
- The voiD parameter is never NULL!
- Once called, the data must consider
- itself detached from the Binder!
- */
- { return; }
- public:
- Binder(UniqueBinderConST) {}
- Binder(unsigned flags = BDR_NO_FREE,
- unsigned maxNodes = BDR_MAXNODES,
- unsigned limit = BDR_LIMIT,
- unsigned delta = BDR_DELTA)
- { construct(flags,maxNodes,limit,delta); }
- Binder(voiDV argv, int argc = 0,
- unsigned flags = BDR_NO_FREE);
- voiDV vector();
- virtual ~Binder();
- /*
- Be sure to override this destructor
- calling allDel() or allFree() in
- the derived class' destructor to
- insure that the correct virtual
- functions are called within allDel()
- and allFree(), i.e. Dfree() and
- Ddetach()!!!
- */
- unsigned Limit() { return limit; }
- unsigned setLimit(unsigned newLimit);
- unsigned pack() { return setLimit(nodes); }
- unsigned Delta() { return delta; }
- unsigned setDelta(unsigned newDelta = BDR_DELTA);
- unsigned Nodes() { return nodes; }
- unsigned MaxNodes() { return maxNodes; }
- unsigned setMaxNodes(unsigned newMaxNodes
- = BDR_MAXNODES);
- unsigned vacancy() { return maxNodes - nodes; }
- unsigned vacancyNonElastic()
- { return limit - nodes; }
- unsigned Flags(unsigned flag =
- BDR_SORTED | BDR_OK_FREE)
- { return (flags & flag); }
- voiD atIns(unsigned n, voiD D);
- voiD atDel(unsigned n);
- int allDel();
- int atFree(unsigned n) { return DFREE(atDel(n)); }
- int allFree();
- voiD atPut(unsigned n, voiD D);
- voiD atGet(unsigned n);
- voiD operator[](unsigned n) { return atGet(n); }
- voiD atXchg(unsigned n, voiD D);
- unsigned index(const voiD D);
- voiD add(voiD D) { return atIns(nodes,D); }
- Binder& operator+=(voiD D)
- { atIns(nodes,D); return *this; }
- Binder& operator+(voiD D)
- { atIns(nodes,D); return *this; }
- voiD subtract(voiD D)
- { return atDel(index(D)); }
- Binder& operator-=(voiD D)
- { atDel(index(D)); return *this; }
- Binder& operator-(voiD D)
- { atDel(index(D)); return *this; }
- int forEach(BDRforEachBlocK B, voiD M = voiD0,
- voiD A = voiD0);
- unsigned firstThat(BDRdetectBlocK B, voiD M = voiD0);
- unsigned lastThat(BDRdetectBlocK B, voiD M = voiD0);
- int collect(BDRcollectBlocK B, BindeR R,
- voiD M = voiD0, voiD A = voiD0);
-
- /* FlexList like primitives: */
-
- voiD top() { return atGet(0); }
- voiD current() { return atGet(curNode); }
- operator voiD() { return atGet(curNode); }
- /*
- The implicit (voiD) cast is meant to be
- used in conjunction with the iterators and
- not the << and >> operators!
- */
- voiD bottom() { return atGet(nodes-1); }
- unsigned CurNode();
- int setCurNode(unsigned n = BDR_MAXNODES);
- int Sorted() { return (flags & BDR_SORTED); }
- void unSort() { flags &= ~BDR_SORTED; }
- BDRcomparE ComparE() { return comparE; }
- void setComparE(BDRcomparE comparE)
- { this->comparE = comparE;
- flags &= ~BDR_SORTED; }
- voiD push(voiD D) { return atIns(0,D); }
- voiD pop() { return atDel(0); }
- int popFree() { return DFREE(atDel(0)); }
- Binder& operator>>(voiD& D)
- { D = atDel(0); return *this; }
- voiD insQ(voiD D)
- { return atIns(nodes,D); }
- Binder& operator<<(voiD D)
- { atIns(nodes,D); return *this; }
- Binder& operator<<(Binder& (*manipulator)
- (Binder& B));
- voiD rmQ() { return atDel(0); }
- int rmQFree() { return DFREE(atDel(0)); }
- voiD unQ() /* Remove from rear of Q */
- { return atDel(nodes-1); }
- int unQFree() { return DFREE(atDel(nodes-1)); }
- voiD ins(voiD D);
- voiD insSort(voiD D);
- voiD del();
- int delFree() { return DFREE(del()); }
- voiD next();
- voiD operator++() { return next(); }
- voiD prev();
- voiD operator--() { return prev(); }
- voiD findFirst(const voiD K);
- voiD findNext (const voiD K);
- voiD findLast (const voiD K);
- voiD findPrev (const voiD K);
- int sort(BDRcomparE comparE = BDRcomparE0);
- };
-
-
- #endif
-